﻿using Android.App;
using Android.Bluetooth;
using Android.Content;
using Android.Content.PM;
using Android.OS;
using Android.Runtime;
using Android.Util;
using Android.Views;
using Android.Widget;
using AndroidX.AppCompat.App;
using AndroidX.LocalBroadcastManager.Content;
using Newtonsoft.Json;
using nhCore;
using System;
using System.Collections.Generic;
using WSYmi.BleService;
using Xamarin.Essentials;
using AlertDialog = AndroidX.AppCompat.App.AlertDialog;

namespace WSYmi.MainAct
{
    [Activity(Label = "@string/app_name", MainLauncher = true, LaunchMode = LaunchMode.SingleTop)]
    public class MainActivity : AppCompatActivity, IServiceConnection
    {
        static string TAG { get; } = typeof(MainActivity).FullName;

        Intent startServiceIntent;
        Intent stopServiceIntent;
        bool isStarted = false;

        /// <summary>
        /// 选中的蓝牙设备
        /// </summary>
        private BluetoothDevice BleDevice { get; set; }

        private BleServiceConnection MyServiceConnection { get; set; }

        /// <summary>
        /// 服务过来的广播接受器
        /// </summary>
        private SrvReceiver SrvReceiver { get; set; }

        /// <summary>
        /// 环境设置
        /// </summary>
        private List<BaseDevice> EnvDevices { get; set; } = new List<BaseDevice>();

        /// <summary>
        /// 文件名列表
        /// </summary>
        private List<CsvFileInfo> FileInfoList { get; set; } = new List<CsvFileInfo>();

        /// <summary>
        /// 文件名列表定制适配器
        /// </summary>
        private static FileNameAdapter FileNameAdapter { get; set; }

        /// <summary>
        /// 正在通讯的设备序号
        /// </summary>
        private string DeviceSn { get; set; }

        /// <summary>
        /// 记录间隔，毫秒
        /// </summary>
        private int RecordIntervalMs { get; set; }
        /// <summary>
        /// 记录持续时间
        /// </summary>
        private int RecordDurationSec { get; set; }

        private Button Btn连接设备 { get; set; }
        private Button Btn开始记录 { get; set; }
        private Spinner Sp保存间隔 { get; set; }
        private Spinner Sp记录时间 { get; set; }
        private TextView Tv气温;
        private TextView Tv气湿;
        private TextView Tv气压;
        private TextView Tv电池;
        private TextView Tv设备编号 { get; set; }

        #region Activity生命期
        protected override void OnCreate(Bundle savedInstanceState)
        {
            base.OnCreate(savedInstanceState);
            Xamarin.Essentials.Platform.Init(this, savedInstanceState);
            // Set our view from the "main" layout resource
            SetContentView(Resource.Layout.activity_main);

            OnNewIntent(this.Intent);

            Log.Debug(TAG, "APP启动。");

            Tv气温 = FindViewById<TextView>(Resource.Id.Tv气温);
            Tv气湿 = FindViewById<TextView>(Resource.Id.Tv气湿);
            Tv气压 = FindViewById<TextView>(Resource.Id.Tv气压);
            Tv电池 = FindViewById<TextView>(Resource.Id.Tv电池);
            Tv设备编号 = FindViewById<TextView>(Resource.Id.Tv设备编号);

            ISharedPreferences preferences = GetSharedPreferences(TAG, FileCreationMode.Private);
            Sp保存间隔 = FindViewById<Spinner>(Resource.Id.Sp保存间隔);
            Sp保存间隔.ItemSelected += OnSpinner时间_ItemSelected;
            Sp保存间隔.SetSelection(preferences.GetInt("保存间隔", 0));//从参数文档读出
            Sp记录时间 = FindViewById<Spinner>(Resource.Id.Sp记录时间);
            Sp记录时间.ItemSelected += OnSpinner时间_ItemSelected;
            Sp记录时间.SetSelection(preferences.GetInt("记录时间", 0));

            Btn连接设备 = FindViewById<Button>(Resource.Id.Btn连接设备);
            Btn连接设备.Click += OnBtn连接设备Click;

            Btn开始记录 = FindViewById<Button>(Resource.Id.Btn开始记录);
            Btn开始记录.Click += OnBtn开始记录Click;


            ListView listView = FindViewById<ListView>(Resource.Id.Ltv保存文件);
            FileInfoList = FileData.GetFileInfos();
            FileNameAdapter = new FileNameAdapter(this, FileInfoList);
            listView.Adapter = FileNameAdapter;
            listView.ItemClick += ListView_ItemClick;

            SrvReceiver = new SrvReceiver(this);

            //启动蓝牙service
            if (!MyServiceConnection?.IsConnected ?? true)
            {
                MyServiceConnection ??= new BleServiceConnection(this); //??= 为空则赋值
                DoBindService();
            }

            LocalBroadcastManager.GetInstance(this).RegisterReceiver(SrvReceiver,
                new IntentFilter(BleService.BleService.ACTION_Server));
        }

        /// <summary>
        /// 开始前景服务
        /// </summary>
        private void StartBleService()
        {
            startServiceIntent = new Intent(this, typeof(BleService.BleService));
            startServiceIntent.SetAction(Constants.ACTION_START_SERVICE);

            //stopServiceIntent = new Intent(this, typeof(BleService.BleService));
            //stopServiceIntent.SetAction(Constants.ACTION_STOP_RECORD);

            if (Build.VERSION.SdkInt >= BuildVersionCodes.O)
            {
                StartForegroundService(startServiceIntent);
            }
            else
            {
                StartService(startServiceIntent);
            }
        }

        /// <summary>
        /// Activity再次回到前台时调用
        /// </summary>
        /// <param name="intent"></param>
        protected override void OnNewIntent(Intent intent)
        {
            if (intent == null)
            {
                return;
            }

            var bundle = intent.Extras;
            if (bundle != null)
            {
                if (bundle.ContainsKey(Constants.SERVICE_STARTED_KEY))
                {
                    isStarted = true;
                }
            }
        }

        /// <summary>
        /// 切换回Activity
        /// </summary>
        protected override void OnResume()
        {
            base.OnResume();
            //if (!MyServiceConnection?.IsConnected ?? false)
            //{
            //    DoBindService();
            //}
        }

        protected override void OnPause()
        {
            base.OnPause();
        }

        protected override void OnStop()
        {
            base.OnStop();
        }

        protected override void OnDestroy()
        {
            LocalBroadcastManager.GetInstance(this).UnregisterReceiver(SrvReceiver);//Activity在后台时也能收到广播
            DoUnBindService();
            base.OnDestroy();
        }

        /// <summary>
        /// 销毁前保存状态
        /// </summary>
        /// <param name="outState"></param>
        protected override void OnSaveInstanceState(Bundle outState)
        {
            outState.PutString("DeviceSn", DeviceSn);
            outState.PutInt("RecordIntervalMs", RecordIntervalMs);
            outState.PutInt("RecordDurationSec", RecordDurationSec);
            outState.PutInt("Btn连接设备.Visibility", (int)Btn连接设备.Visibility);
            outState.PutInt("Btn开始记录.Visibility", (int)Btn开始记录.Visibility);
            base.OnSaveInstanceState(outState);
        }

        /// <summary>
        /// 重启后恢复状态
        /// </summary>
        /// <param name="savedState"></param>
        protected override void OnRestoreInstanceState(Bundle savedState)
        {
            base.OnRestoreInstanceState(savedState);
            DeviceSn = savedState.GetString("DeviceSn");
            RecordIntervalMs = savedState.GetInt("RecordIntervalMs");
            RecordDurationSec = savedState.GetInt("RecordDurationSec");
            Btn连接设备.Visibility = (ViewStates)savedState.GetInt("Btn连接设备.Visibility");
            Btn开始记录.Visibility = (ViewStates)savedState.GetInt("Btn开始记录.Visibility");
        }
        #endregion

        #region 控件响应
        /// <summary>
        /// 选中项转化为时间，赋予对应属性，参数保存
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void OnSpinner时间_ItemSelected(object sender, AdapterView.ItemSelectedEventArgs e)
        {
            Spinner spinner = sender as Spinner;
            string strTitle = spinner.SelectedItem.ToString();
            string result = System.Text.RegularExpressions.Regex.Replace(strTitle, @"[^0-9]+", "");//返回字符串包含的数字

            if (int.TryParse(result, out int intervar))
            {
                if (strTitle.IndexOf("分") >= 0)
                {
                    intervar *= 60;
                }
            }
            else
            {
                intervar = -1;//工作时间不指定时，为-1
            }

            if ((string)spinner.Tag == "保存间隔")
            {
                RecordIntervalMs = intervar * 1000;//单位毫秒
            }
            else
            {
                RecordDurationSec = intervar;//单位秒
            }

            //参数保存菜单位置
            ISharedPreferences preferences = GetSharedPreferences(TAG, FileCreationMode.Private);
            ISharedPreferencesEditor editor = preferences.Edit();
            editor.PutInt((string)spinner.Tag, spinner.SelectedItemPosition);
            editor.Commit();
        }

        private void OnBtn连接设备Click(object sender, EventArgs e)
        {
            Intent intent = new Intent(this, typeof(ConnectAct.ConnectActivity));
            intent.SetFlags(ActivityFlags.SingleTop);
            StartActivityForResult(intent, Constants.Request_Code_Connect_Activity);
        }

        /// <summary>
        /// 根据IsCollecting状态，开始记录或停止记录
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void OnBtn开始记录Click(object sender, EventArgs e)
        {
            Cmd cmd = MyServiceConnection.Binder.Service.Cmds.Find(c => c.SentCmd.Code == 4);
            if (CsvFileInfo.IsCollecting)
            {
                Btn开始记录.Text = GetString(Resource.String.开始记录);
                Sp保存间隔.Enabled = true;
                Sp记录时间.Enabled = true;
                CsvFileInfo.IsCollecting = false;
                FileNameAdapter.NotifyDataSetChanged();
                MyServiceConnection.Binder.Service.RecordStop();//停止记录
                DeviceDisplay.KeepScreenOn = false;
            }
            else
            {
                EditText etInput = new EditText(this);

                var ad = new AlertDialog.Builder(this);
                ad.SetTitle("请输入文件名");
                ad.SetView(etInput);
                ad.SetNegativeButton("取消", (sender, args) => { });
                ad.SetPositiveButton("确定", (sender, args) =>
                {
                    string fileName = etInput.Text.Replace(',', '.');//文件名不能出现','
                    if (string.IsNullOrEmpty(fileName))
                    {
                        Toast.MakeText(this, "文件名不能为空！", ToastLength.Long).Show();
                        return;
                    }

                    //更新文件列表
                    CsvFileInfo myFileName = new CsvFileInfo()
                    {
                        Name = fileName,
                        DeviceSn = DeviceSn,
                        Time = $"{DateTime.Now:yyyy-MM-dd HH:mm:ss}",
                    };

                    fileName = $"{myFileName.Name},{myFileName.DeviceSn},{myFileName.Time}.csv";
                    myFileName.FileName = fileName;

                    if (MyServiceConnection.Binder.Service.RecordStart(fileName, RecordIntervalMs, RecordDurationSec))
                    {
                        FileInfoList.Insert(0, myFileName); //文件建立成功才插入到列表第一个
                        CsvFileInfo.IsCollecting = true;
                        FileNameAdapter.NotifyDataSetChanged();

                        Btn开始记录.Text = GetString(Resource.String.停止记录);
                        Sp保存间隔.Enabled= false;
                        Sp记录时间.Enabled = false;
                        StartBleService();
                        PowerSettings();
                        DeviceDisplay.KeepScreenOn = true;
                    }
                });

                ad.Show();
            }
        }



        void PowerSettings()
        {
            //REQUEST_IGNORE_BATTERY_OPTIMIZATIONS
            if (Build.VERSION.SdkInt >= BuildVersionCodes.M)
            {
                Intent intent = new Intent();
                string packageName = AppInfo.PackageName;
                PowerManager pm = (PowerManager)GetSystemService(Service.PowerService);
                if (!pm.IsIgnoringBatteryOptimizations(packageName))
                {

                    intent.SetAction(Android.Provider.Settings.ActionRequestIgnoreBatteryOptimizations);
                    intent.SetData(Android.Net.Uri.Parse("package:" + packageName));
                    StartActivity(intent);
                }
            }
        }

        /// <summary>
        /// 文件列表点击
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void ListView_ItemClick(object sender, AdapterView.ItemClickEventArgs e)
        {
            Intent intent = new Intent(this, typeof(TableAct.TableActivity));

            intent.PutExtra("FileInfo", JsonConvert.SerializeObject(FileInfoList[e.Position]));
            intent.SetFlags(ActivityFlags.SingleTop);
            //StartActivity(intent);
            StartActivityForResult(intent, Constants.Request_Code_Table_Activity);
        }
        #endregion

        /// <summary>
        /// 用户权限选择后的返回
        /// </summary>
        /// <param name="requestCode"></param>
        /// <param name="permissions"></param>
        /// <param name="grantResults"></param>
        public override void OnRequestPermissionsResult(int requestCode, string[] permissions, [GeneratedEnum] Android.Content.PM.Permission[] grantResults)
        {
            Xamarin.Essentials.Platform.OnRequestPermissionsResult(requestCode, permissions, grantResults);

            base.OnRequestPermissionsResult(requestCode, permissions, grantResults);
        }

        /// <summary>
        /// 子窗口返回
        /// </summary>
        /// <param name="requestCode"></param>
        /// <param name="resultCode"></param>
        /// <param name="data"></param>
        protected override void OnActivityResult(int requestCode, [GeneratedEnum] Result resultCode, Intent data)
        {
            if ((requestCode == Constants.Request_Code_Connect_Activity && resultCode == Result.Ok))
            {
                if (data == null) return;
                BluetoothDevice bleDevice = (BluetoothDevice)data.GetParcelableExtra("Device");
                string address = data.GetStringExtra("Address");

                //连接蓝牙设备
                if (MyServiceConnection.Binder.Service.Connect(address))
                {
                    Btn连接设备.Enabled = false; ////连接蓝牙到成功有间隔，避免误按
                }
            }
            else if (requestCode == Constants.Request_Code_Table_Activity && resultCode == Result.Ok)
            {
                CsvFileInfo fileInfo = FileInfoList.Find(f => f.FileName == data.GetStringExtra("pathFileName"));
                FileInfoList.Remove(fileInfo);
                FileNameAdapter.NotifyDataSetChanged();
            }
        }

        #region Service连接相关
        /// <summary>
        /// 绑定服务到本窗体
        /// </summary>
        void DoBindService()
        {
            Intent serviceToStart = new Intent(this, typeof(WSYmi.BleService.BleService));
            _ = BindService(serviceToStart, MyServiceConnection, Bind.AutoCreate);
        }

        /// <summary>
        /// 解除绑定
        /// </summary>
        void DoUnBindService()
        {
            if (MyServiceConnection?.IsConnected ?? false)
            {
                UnbindService(MyServiceConnection);
            }
        }

        /// <summary>
        /// 服务连接
        /// </summary>
        /// <param name="name"></param>
        /// <param name="service"></param>
        /// <exception cref="NotImplementedException"></exception>
        public void OnServiceConnected(ComponentName name, IBinder service)
        {
            if (!MyServiceConnection.Binder.Service.Initialize())

            {
                Toast.MakeText(Application.Context, "后台服务初始化失败，App不能运行", ToastLength.Long).Show();
                return;
            }
        }

        /// <summary>
        /// 服务断开
        /// </summary>
        /// <param name="name"></param>
        /// <exception cref="NotImplementedException"></exception>
        public void OnServiceDisconnected(ComponentName name)
        {
            Toast.MakeText(Application.Context, "后台服务已断开，App应退出", ToastLength.Long).Show();
        }
        #endregion

        /// <summary>
        /// 接受广播
        /// </summary>
        /// <param name="context"></param>
        /// <param name="intent"></param>
        public void OnReceive(Context context, Intent intent)
        {
            //消息
            string res = intent.GetStringExtra(BleService.BleService.KEY_Message);
            if (!string.IsNullOrEmpty(res))
            {
                Toast.MakeText(Application.Context, res, ToastLength.Long).Show();
            }

            //状态
            EnumMessageHandler enState = (EnumMessageHandler)intent.GetIntExtra(BleService.BleService.KEY_State, 0);
            switch (enState)
            {
                case EnumMessageHandler.BleConnected: //蓝牙已连接
                    Btn连接设备.Visibility = ViewStates.Gone;
                    Btn开始记录.Visibility = ViewStates.Visible;
                    Toast.MakeText(Application.Context, "蓝牙设备连接成功。", ToastLength.Long).Show();
                    break;
                case EnumMessageHandler.BleDisconnected: //蓝牙已断开
                    Btn连接设备.Enabled = true; //连接蓝牙到成功有间隔，避免误按
                    Btn连接设备.Visibility = ViewStates.Visible;
                    Btn开始记录.Visibility = ViewStates.Gone;
                    string msg = "蓝牙设备断开连接。";
                    if (CsvFileInfo.IsCollecting)
                    {
                        OnBtn开始记录Click(this, null);//停止记录
                        msg += "记录停止。";
                    }
                    Toast.MakeText(Application.Context, msg, ToastLength.Long).Show();

                    //如果正在记录应停止
                    break;
                case EnumMessageHandler.NotBleDevice: //不时兼容蓝牙设备
                    var dialog = new AlertDialog.Builder(this);
                    dialog.SetTitle("警告");
                    dialog.SetMessage("不是兼容蓝牙设备。");
                    //设置警告对话框的按钮
                    dialog.SetPositiveButton("确定", delegate
                    {

                    });
                    dialog.Show();
                    break;
                default:
                    break;
            }

            //解析后、设备序号
            if (!string.IsNullOrEmpty(intent.GetStringExtra(BleService.BleService.KEY_DeviceSn)))
            {
                DeviceSn = intent.GetStringExtra(BleService.BleService.KEY_DeviceSn);
                Tv设备编号.Text = intent.GetStringExtra(BleService.BleService.KEY_DeviceSn);
                Tv设备编号.Visibility = Android.Views.ViewStates.Visible;
            }

            //解析后、气象要素
            string strWeathers = intent.GetStringExtra(BleService.BleService.KEY_Weather);
            if (strWeathers != null)
            {
                Dictionary<int, Weather> indexWeater = JsonConvert.DeserializeObject<Weathers>(strWeathers).Values;
                var w = Util.GetDictionaryElements<int, Weather>(indexWeater, 4);
                Tv气温.Text = w.StrValue + w.Config.Unit;
                w = Util.GetDictionaryElements<int, Weather>(indexWeater, 5);
                Tv气湿.Text = w.StrValue + w.Config.Unit;
                w = Util.GetDictionaryElements<int, Weather>(indexWeater, 6);
                Tv气压.Text = w.StrValue + w.Config.Unit;
                w = Util.GetDictionaryElements<int, Weather>(indexWeater, 3);
                Tv电池.Text = w.StrValue + w.Config.Unit;
                if (w.Value < 30)
                {
                    Tv电池.SetTextColor(Resources.GetColor(Resource.Color.报警红, Theme));
                }
                else
                {
                    Tv电池.SetTextColor(Resources.GetColor(Resource.Color.黄色字, Theme));
                }
            }
        }
    }
}